package com.zhs.type;

import java.util.ArrayList;
import java.util.Hashtable;

/**
 * Contains the info for the variables with in this scope, and the parent scope
 * for hierarchical search.
 * 
 */
public class Scope {
	private Scope parent;

	private Hashtable<String, Variable> variables = new Hashtable<String, Variable>();

	public Scope getParent() {
		return parent;
	}

	public Hashtable<String, Variable> getVariables() {
		return variables;
	}

	public void setParent(Scope parent) {
		this.parent = parent;
	}

	/**
	 * search the variable with given varName across the scope. Search starts
	 * with this scope, and will handle the search to parent scope if current
	 * scope contains no match for the given varName. Also, the search return
	 * immediately after a match is found, so local variables will override the
	 * global ones.
	 * 
	 * @param varName
	 * @return variable with given id, null if not found
	 */
	public Variable lookupVariable(String varName) {
		Variable var = variables.get(varName);
		if (var == null && parent != null) {
			var = parent.lookupVariable(varName);
		}
		return var;
	}

	/**
	 * Add the var table of another Scope to this one.<br>
	 * <b> Caution: Overwriting is possible </b>
	 * 
	 * @param otherScope
	 */
	public void addScope(Scope otherScope) {
		this.variables.putAll(otherScope.getVariables());
	}

	public void addScope(ArrayList<Variable> otherScope) {
		for (Variable v : otherScope) {
			this.variables.put(v.getVarName(), v);
		}
	}

	/**
	 * @param var
	 * @return null if no duplicate var exists
	 */
	public Variable addVariable(Variable var) {
		return this.variables.put(var.getVarName(), var);
	}

	public Scope clone() {
		Scope replica = new Scope();
		replica.addScope(this);
		replica.parent = this.parent;
		return replica;
	}
}
